package dm.daemon;

import java.sql.SQLException;

import org.dom4j.DocumentException;

import algo.LoadBalance;
import dm.bsi.Deployment;
import dm.bsi.Log;
import dm.bsi.MSDeployment;
import dm.bsi.MSSDeployment;
import dm.bsi.Node;
import dm.bsi.Service;
import dm.bsi.WDeployment;
import indi.zjh.dp.db.Configuration;
import indi.zjh.dp.db.Session;
import indi.zjh.dp.error.CommandExecuteException;
import indi.zjh.dp.error.ConfigureInvalidException;
import indi.zjh.dp.error.UnsuportedFieldException;
import indi.zjh.dp.util.SystemCmd;

public class DeploymentDaemon implements Runnable{

	private static final int STATE_INIT = 0; // 初始化
	private static final int STATE_PROCESS = 1; // 安装镜像
	
	private static final int INIT_INTERVAL = 5000; // 状态机初始化运行时间间隔, 单位:毫秒
	
	protected int interval = INIT_INTERVAL; // 当前状态机运行时间间隔
	
	protected Deployment deployment;
	protected int state = 0;
	protected int prestate = 9999;
	
	public DeploymentDaemon(Deployment deployment)
	{
		this.deployment = deployment;
		
	}
	
	private void changeState(int newState)
	{
		this.prestate = this.state;
		this.state = newState;
	}
	
	public void run() {
		// TODO Auto-generated method stub
		
		while(true)
		{
			Session session = null;
			String cmd = null;
			String response = null;
			try
			{
				session = Configuration.getSessionFactory().createSession();
				
				if(this.deployment.getMode() == Deployment.MODE_WORKER)
					this.deployment = (WDeployment)session.getById(WDeployment.class, this.deployment.getSpecId(WDeployment.class));
				else if(this.deployment.getMode() == Deployment.MODE_MASTER_SLAVE)
					this.deployment = (MSDeployment)session.getById(MSDeployment.class, this.deployment.getSpecId(MSDeployment.class));
				else
					this.deployment = (MSSDeployment)session.getById(MSSDeployment.class, this.deployment.getSpecId(MSSDeployment.class));
				
				switch (this.state) {
				case STATE_INIT:
					// 检查部署参数是否合法
					
					if(this.prestate != this.state) Log.info(session, deployment, "检查部署参数是否合法");
					
					try {
						this.deployment.checkConfig();
						if(this.prestate != this.state) Log.success(session, this.deployment, "该部署参数合法");
						this.changeState(STATE_PROCESS);
					} catch (ConfigureInvalidException e) {
						// TODO: handle exception
						if(this.prestate != this.state) Log.failure(session, this.deployment, e.getMessage());	
					}
					
					
					break;
				
				case STATE_PROCESS:
					// 调研部署安装镜像和处理容器方法
					
					try
					{
						this.deployment.processContainer(session);
					}
					catch (Exception e) {
						// TODO: handle exception
						Log.failure(session, this.deployment, e.getMessage());
					}
					
					break;

				default:
					break;
				}
				
				session.save(this.deployment).commit();
			}
			catch(CommandExecuteException e)
			{
				try {
					if(session != null)
					{
						Log.failure(session, this.deployment, "运行cmd失败:"+e.getMessage());
						session.commit();
					}
				} catch (ClassNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (UnsuportedFieldException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (DocumentException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
			catch(Exception e)
			{
				if(session != null)
				{
					try {
						session.rollback();
					} catch (SQLException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				e.printStackTrace();
			}
			finally {
				if(session != null)
				{
					try {
						session.close();
					} catch (DocumentException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			
			try {
				Thread.sleep(interval);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
